﻿using ProjectFootball.MVC.Foundation.ResourceLibrary;
using ProjectFootball.MVC.Models.EntityFramework.Contexts;
using ProjectFootball.MVC.Models.EntityFramework.Entities;
using System;
using System.Data.Entity.Migrations;
using System.Linq;
using System.Web.Security;
using WebMatrix.WebData;

namespace ProjectFootball.MVC.Models.EntityFramework.Migrations
{
    internal sealed class Configuration : DbMigrationsConfiguration<PFDBContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
            AutomaticMigrationDataLossAllowed = true;
        }

        private PFDBContext context;
        private int adminUserId
        {
            get { return context.UserProfiles.Single(u => u.UserName == "admin@projectfootball.co.uk").UserId; }
        }
            
        protected override void Seed(PFDBContext context)
        {
            this.context = context;

            CreateSecurityData();
            CreateCountries();
            CreateCompetitions();
            CreateLookupCompetitions();
        }

        #region SecurityData
        private void CreateSecurityData()
        {
            WebSecurity.InitializeDatabaseConnection("PFDBContext", "User", "UserId", "UserName", true);

            var roles = (SimpleRoleProvider)Roles.Provider;
            var membership = (SimpleMembershipProvider)System.Web.Security.Membership.Provider;

            if (!roles.RoleExists("Admin"))
                roles.CreateRole("Admin");

            if (!roles.RoleExists("Superuser"))
                roles.CreateRole("Superuser");

            if (!roles.RoleExists("User"))
                roles.CreateRole("User");
            
            if (membership.GetUser("admin@projectfootball.co.uk", false) == null)
                membership.CreateUserAndAccount("admin@projectfootball.co.uk", "admin");

            if (!roles.GetRolesForUser("admin@projectfootball.co.uk").Contains("Admin"))
                roles.AddUsersToRoles(new[] { "admin@projectfootball.co.uk" }, new[] { "Admin" });

            if (membership.GetUser("superuser@projectfootball.co.uk", false) == null)
                membership.CreateUserAndAccount("superuser@projectfootball.co.uk", "superuser");

            if (!roles.GetRolesForUser("superuser@projectfootball.co.uk").Contains("Superuser"))
                roles.AddUsersToRoles(new[] { "superuser@projectfootball.co.uk" }, new[] { "Superuser" });

            if (membership.GetUser("user@projectfootball.co.uk", false) == null)
                membership.CreateUserAndAccount("user@projectfootball.co.uk", "user");

            if (!roles.GetRolesForUser("user@projectfootball.co.uk").Contains("User"))
                roles.AddUsersToRoles(new[] { "user@projectfootball.co.uk" }, new[] { "User" });

            context.SaveChanges();
        }
        #endregion

        #region Countries
        private void CreateCountries()
        {
            AddCountry("England", _DateTime.LowDate.ToShortDateString(), _DateTime.HighDate.ToShortDateString());
            context.SaveChanges();
        }

        private void AddCountry(string countryName, string startDate, string endDate)
        {
            context.Countries.AddOrUpdate(new Country()
            {
                Pk = Guid.NewGuid(),
                ApprovalGuid = Guid.NewGuid(),
                CountryName = countryName,
                ActiveFrom = DateTime.Parse(startDate),
                ActiveTo = DateTime.Parse(endDate),
                IsPublic = true,
                IsApproved = true,
                IsMarkedForDeletion = false,
                OwnerUserId = adminUserId,
                AuditUserId = adminUserId,
                AuditTimestamp = DateTime.Now
            });
        }
        #endregion

        #region Competitions
        private void CreateCompetitions()
        {
            Guid competitionGuid = AddCompetition("Football League", "England", "01/07/1888", "30/06/1892");
            competitionGuid = AddCompetition("Football League First Division", "England", "01/07/1892", "30/06/1992");

            #region PremierLeague
            competitionGuid = AddCompetition("Premier League", "England", "01/07/1992", _DateTime.HighDate.ToShortDateString());
            AddCampaign(competitionGuid, "01/08/2013", "31/05/2014");
            #endregion

            competitionGuid = AddCompetition("Football League Second Division", "England", "01/07/1892", "30/06/1992");
            competitionGuid = AddCompetition("Football League First Division", "England", "01/07/1992", "30/06/2004");
            competitionGuid = AddCompetition("Football League Championship", "England", "01/07/2004", _DateTime.HighDate.ToShortDateString());

            competitionGuid = AddCompetition("Football League Third Division", "England", "01/07/1920", "30/06/1921");
            competitionGuid = AddCompetition("Football League Third Division(North)", "England", "01/07/1921", "30/06/1958");
            competitionGuid = AddCompetition("Football League Third Division(South)", "England", "01/07/1921", "30/06/1958");
            competitionGuid = AddCompetition("Football League Third Division", "England", "01/07/1958", "30/06/1992");
            competitionGuid = AddCompetition("Football League Second Division", "England", "01/07/1992", "30/06/2004");
            competitionGuid = AddCompetition("League One", "England", "01/07/2004", _DateTime.HighDate.ToShortDateString());

            competitionGuid = AddCompetition("Football League Fourth Division", "England", "01/07/1958", "30/06/1992");
            competitionGuid = AddCompetition("Football League Third Division", "England", "01/07/1992", "30/06/2004");
            competitionGuid = AddCompetition("League Two", "England", "01/07/2004", _DateTime.HighDate.ToShortDateString());

            competitionGuid = AddCompetition("Alliance Premier League", "England", "01/07/1979", "30/06/1987");
            competitionGuid = AddCompetition("Football Conference", "England", "01/07/1987", "30/06/2004");
            competitionGuid = AddCompetition("Conference National", "England", "01/07/2004", _DateTime.HighDate.ToShortDateString());

            context.SaveChanges();
        }

        private Guid AddCompetition(string competitionName, string countryName, string startDate, string endDate)
        {
            Guid newGuid = Guid.NewGuid();

            context.Competitions.AddOrUpdate(new Competition()
            {
                Pk = newGuid,
                ApprovalGuid = Guid.NewGuid(),
                CompetitionName = competitionName,
                CompetitionType = CompetitionType.League,
                LocationType = LocationType.National,
                CountryGuid = context.Countries.Single(c => c.CountryName == countryName).Pk,
                ActiveFrom = DateTime.Parse(startDate),
                ActiveTo = DateTime.Parse(endDate),
                IsPublic = true,
                IsApproved = true,
                IsMarkedForDeletion = false,
                OwnerUserId = adminUserId,
                AuditUserId = adminUserId,
                AuditTimestamp = DateTime.Now
            });

            return newGuid;
        }

        private void CreateLookupCompetitions()
        {
            context.LookupCompetitions.Add(new LookupCompetition() {LookupCompetitionGuid = Guid.NewGuid(), CompetitionGuid = GetCompetitionGuid("Premier League"), ImportSite = ImportSite.Espn, SiteCompetitionId = "eng.1" });
            context.LookupCompetitions.Add(new LookupCompetition() {LookupCompetitionGuid = Guid.NewGuid(), CompetitionGuid = GetCompetitionGuid("Football League Championship"), ImportSite = ImportSite.Espn, SiteCompetitionId = "eng.2" });
            context.LookupCompetitions.Add(new LookupCompetition() {LookupCompetitionGuid = Guid.NewGuid(), CompetitionGuid = GetCompetitionGuid("League One"), ImportSite = ImportSite.Espn, SiteCompetitionId = "eng.3" });
            context.LookupCompetitions.Add(new LookupCompetition() {LookupCompetitionGuid = Guid.NewGuid(), CompetitionGuid = GetCompetitionGuid("League Two"), ImportSite = ImportSite.Espn, SiteCompetitionId = "eng.4" });
            context.LookupCompetitions.Add(new LookupCompetition() {LookupCompetitionGuid = Guid.NewGuid(), CompetitionGuid = GetCompetitionGuid("Conference National"), ImportSite = ImportSite.Espn, SiteCompetitionId = "eng.5" });
        }

        private Guid GetCompetitionGuid(string competitionName)
        {
            return context.Competitions.Single(c => c.CompetitionName == competitionName && c.ActiveTo == _DateTime.HighDate).Pk;
        }
        #endregion

        #region Campaigns
        private void AddCampaign(Guid competitionGuid, string startDate, string endDate)
        {
            context.Campaigns.AddOrUpdate(new Campaign()
            {
                Pk = Guid.NewGuid(),
                ApprovalGuid = Guid.NewGuid(),
                CompetitionGuid = competitionGuid,
                StartDate = DateTime.Parse(startDate),
                EndDate = DateTime.Parse(endDate),
                IsPublic = true,
                IsApproved = true,
                IsMarkedForDeletion = false,
                OwnerUserId = adminUserId,
                AuditUserId = adminUserId,
                AuditTimestamp = DateTime.Now
            });
        }
        #endregion
    }
}